package com.chenjun.designpattern.behavior.command;

/**
 * <p>
 * 意图：将一个请求封装为一个对象，从而可用不同的请求对客户进行参数化；对请求排队或记录日志，以及支持可撤销的操作
 * 动机：将”发出请求的对象”和”接收与执行这些请求的对象”分隔开来。 效果： 1)、command模式将调用操作的对象和实现该操作的对象解耦
 * 2)、可以将多个命令装配成一个复合命令，复合命令是Composite模式的一个实例 3)、增加新的command很容易，无需改变已有的类
 * </p>
 * 
 * @author Administrator
 *
 */
public class 完整命令模式
{
	public static void main(String[] args)
	{
		// 创建CMD接受者
		Receiver receiver = new Receiver();
		// 创建命令对象，并设置它的接受者
		Command2 command2 = new ConcreteCommand2(receiver);

		// 创建调用者，将命令对象传进去
		Invoker invoker = new Invoker();
		invoker.setCmd(command2);

		// run
		invoker.runCommand();
		invoker.unDoCommand();
	}
}

interface Command2
{
	// 执行命令
	public void execute();

	// 取消命令
	public void cancle();
}

class Receiver
{
	public void action()
	{
		System.out.println("接受者执行命令...");
	}

	public void unAction()
	{
		System.out.println("接受者忽略命令...");
	}
}

class ConcreteCommand2 implements Command2
{
	private Receiver receiver;
	private String state;

	public ConcreteCommand2(Receiver receiver)
	{
		this.receiver = receiver;
	}

	@Override
	public void execute()
	{
		System.out.println("ConcreteCommand2 执行命令...");
	}

	@Override
	public void cancle()
	{
		System.out.println("ConcreteCommand2 撤销命令...");
	}

	public Receiver getReceiver()
	{
		return receiver;
	}

	public void setReceiver(Receiver receiver)
	{
		this.receiver = receiver;
	}

	public String getState()
	{
		return state;
	}

	public void setState(String state)
	{
		this.state = state;
	}

}

class Invoker
{
	private Command2 cmd;

	// getter
	public Command2 getCmd()
	{
		return cmd;
	}

	// setter
	public void setCmd(Command2 cmd)
	{
		this.cmd = cmd;
	}

	public void runCommand()
	{
		cmd.execute();
	}

	public void unDoCommand()
	{
		cmd.cancle();
	}
}
